package app;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import sets.FuzzySetType1;
import sets.IFuzzySet;
import sets.IntervalFuzzySet1;
import universe.Dense;
import universe.Discrete;
import universe.IUniverseOfDiscourse;
import utils.Point;

import linguistic.Quantifier;
import linguistic.Variable;
import memberships.MembershipFunction;
import memberships.Trapezoidal;
import memberships.Triangular;

public class ObjectReader {
	
	private List<Quantifier> quantifiers = new ArrayList<>();
	private List<Variable> variables = new ArrayList<>();
	private List<String> linesFromFile = new ArrayList<>();
	
	private List<IFuzzySet> sets = new ArrayList<>();
	
	public List<Quantifier> getQuantifiers() {
		return quantifiers;
	}
	
	public List<Variable> getVariables() {
		return variables;
	}
	
	public void createFromFile(String filename) {
		
		try {
			FileInputStream fstream = new FileInputStream(filename);
			DataInputStream in = new DataInputStream(fstream);
			BufferedReader br = new BufferedReader(new InputStreamReader(in));
			
			String strLine;
			
			while ((strLine = br.readLine()) != null) {
				//System.out.println(strLine);
				linesFromFile.add(strLine);
			}
			br.close();
		} catch (Exception e) {
			//
		}
		construct();
	}
	
	private void construct() {
		boolean nowQuantifiers = false;
		boolean nowVariables = false;
		
		for (String line : linesFromFile) {
			//System.out.println(line);
			
			if (line.equals("Variables")) {
				nowQuantifiers = false;
				nowVariables = true;
				continue;
			}
			
			
			if (nowQuantifiers == true) {
				// One line per one quantifier
				String[] elements = line.split(",");
				
				IUniverseOfDiscourse universe = null;
				// Create universe of discourse
				if (elements[4].equals("DENSE")) {
					String[] uniBounds = elements[5].split(";");
					universe = new Dense(Double.parseDouble(uniBounds[0]), Double.parseDouble(uniBounds[1]));
					//System.out.println(Double.parseDouble(uniBounds[0]) + " " + Double.parseDouble(uniBounds[1]));
					
				} else if (elements[4].equals("DISCRETE")) {
					universe = new Discrete();
					String[] uniElements = elements[5].split(";");
					for (int i = 0; i < uniElements.length; ++i) {
						((Discrete)universe).addElement(Double.parseDouble(uniElements[i]));
					}
				}
				
				MembershipFunction membership = null;
				// Create membership function
				if (elements[1].equals("TYPE1")) {
					if (elements[2].equals("TRIANGAL")) {
						String[] points = elements[3].split(" ");
						membership = new Triangular();
						((Triangular)membership).setA(new Point(Double.parseDouble(points[0].split(";")[0]), Double.parseDouble(points[0].split(";")[1])));
						((Triangular)membership).setB(new Point(Double.parseDouble(points[1].split(";")[0]), Double.parseDouble(points[1].split(";")[1])));
						((Triangular)membership).setC(new Point(Double.parseDouble(points[2].split(";")[0]), Double.parseDouble(points[2].split(";")[1])));
					} else if (elements[2].equals("TRAPEZOIDAL")) {
						String[] points = elements[3].split(" ");
						membership = new Trapezoidal();
						((Trapezoidal)membership).setA(new Point(Double.parseDouble(points[0].split(";")[0]), Double.parseDouble(points[0].split(";")[1])));
						((Trapezoidal)membership).setB(new Point(Double.parseDouble(points[1].split(";")[0]), Double.parseDouble(points[1].split(";")[1])));
						((Trapezoidal)membership).setC(new Point(Double.parseDouble(points[2].split(";")[0]), Double.parseDouble(points[2].split(";")[1])));
						((Trapezoidal)membership).setD(new Point(Double.parseDouble(points[3].split(";")[0]), Double.parseDouble(points[3].split(";")[1])));
					}
				}
				
				
				IFuzzySet set = null;;
				// Create fuzzy set
				if (elements[1].equals("TYPE1")) {
					set = new FuzzySetType1();
				}
				
				set.setMembershipFunction(membership);
				set.setUniverseOfDiscorse(universe);
				
				Quantifier quantifier = new Quantifier();
				quantifier.setName(elements[0]);
				quantifier.setSet(set);
				
				quantifiers.add(quantifier);
			}
			
			
			/*if (nowVariables == true) {
				if (line.substring(0, 1).equals("H")) {
					variable = new Variable();
					String[] elements = line.split(",");
					variable.setName(elements[1]);
					
					IUniverseOfDiscourse universe = null;
					if (elements[3].equals("DENSE")) {
						universe = new Dense();
						((Dense)universe).addInterval(Double.parseDouble(elements[4].split(";")[0]), Double.parseDouble(elements[4].split(";")[1]));
					} else if (elements[3].equals("DISCRETE")) {
						universe = new Discrete();
						System.out.println("Not implemented!");
					}
					
					variable.setUniverse(universe);
					variables.add(variable);
				} else if (line.substring(0, 1).equals("S")) {
					// Create fuzzy set starting from universe
					String[] elements = line.split(",");
					IUniverseOfDiscourse universe = null;
					if (elements[6].equals("DENSE")) {
						universe = new Dense();
						((Dense)universe).addInterval(Double.parseDouble(elements[7].split(";")[0]), Double.parseDouble(elements[7].split(";")[1]));
					} else if (elements[6].equals("DISCRETE")) {
						System.out.println("Not implemented");
					}
					
					MembershipFunction membership = null;
					if (elements[4].equals("TRIANGAL")) {
						String[] points = elements[5].split(" ");
						membership = new Triangular();
						((Triangular)membership).setA(new Point(Double.parseDouble(points[0].split(";")[0]), Double.parseDouble(points[0].split(";")[1])));
						((Triangular)membership).setB(new Point(Double.parseDouble(points[1].split(";")[0]), Double.parseDouble(points[1].split(";")[1])));
						((Triangular)membership).setC(new Point(Double.parseDouble(points[2].split(";")[0]), Double.parseDouble(points[2].split(";")[1])));
					} else if (elements[4].equals("TRAPEZOIDAL")) {
						String[] points = elements[5].split(" ");
						membership = new Trapezoidal();
						((Trapezoidal)membership).setA(new Point(Double.parseDouble(points[0].split(";")[0]), Double.parseDouble(points[0].split(";")[1])));
						((Trapezoidal)membership).setB(new Point(Double.parseDouble(points[1].split(";")[0]), Double.parseDouble(points[1].split(";")[1])));
						((Trapezoidal)membership).setC(new Point(Double.parseDouble(points[2].split(";")[0]), Double.parseDouble(points[2].split(";")[1])));
						((Trapezoidal)membership).setD(new Point(Double.parseDouble(points[3].split(";")[0]), Double.parseDouble(points[3].split(";")[1])));
					}
					
					IFuzzySet set = new FuzzySetType1();
					set.setColumn(elements[2]);
					set.setUniverseOfDiscorse(universe);
					set.setMembershipFunction(membership);
					
					boolean isActive = false;
					if (elements[8].equals("TRUE")) {
						isActive = true;
					} else if (elements[8].equals("FALSE")) {
						isActive = false;
					}
					
					variable.addFuzzySet(elements[1], set, isActive);
					variable.setColumn(elements[2]);
				}
			}*/

			// Create set of summarizers
			if (nowVariables == true) {
				String[] elements = line.split(",");
				// Create universe
				IUniverseOfDiscourse universe = null;
				if (elements[8].equals("DENSE")) {
					universe = new Dense();
					((Dense)universe).addInterval(Double.parseDouble(elements[9].split(";")[0]), Double.parseDouble(elements[9].split(";")[1]));
				} else if (elements[8].equals("DISCRETE")) {
					universe = new Discrete();
					System.out.println("Not implemented!");
				}
				
				// Create membership(s)
				MembershipFunction membership = null;
				MembershipFunction upperMembership = null;
				MembershipFunction lowerMembership = null;
				if (elements[3].equals("INTERVAL")) {
					// Lower membership function
					if (elements[4].equals("TRIANGAL")) {
						String[] points = elements[5].split(" ");
						lowerMembership = new Triangular();
						((Triangular)lowerMembership).setA(new Point(Double.parseDouble(points[0].split(";")[0]), Double.parseDouble(points[0].split(";")[1])));
						((Triangular)lowerMembership).setB(new Point(Double.parseDouble(points[1].split(";")[0]), Double.parseDouble(points[1].split(";")[1])));
						((Triangular)lowerMembership).setC(new Point(Double.parseDouble(points[2].split(";")[0]), Double.parseDouble(points[2].split(";")[1])));
					} else if (elements[4].equals("TRAPEZOIDAL")) {
						String[] points = elements[5].split(" ");
						lowerMembership = new Trapezoidal();
						((Trapezoidal)lowerMembership).setA(new Point(Double.parseDouble(points[0].split(";")[0]), Double.parseDouble(points[0].split(";")[1])));
						((Trapezoidal)lowerMembership).setB(new Point(Double.parseDouble(points[1].split(";")[0]), Double.parseDouble(points[1].split(";")[1])));
						((Trapezoidal)lowerMembership).setC(new Point(Double.parseDouble(points[2].split(";")[0]), Double.parseDouble(points[2].split(";")[1])));
						((Trapezoidal)lowerMembership).setD(new Point(Double.parseDouble(points[3].split(";")[0]), Double.parseDouble(points[3].split(";")[1])));
					}
					// Upper membership function
					if (elements[6].equals("TRIANGAL")) {
						String[] points = elements[7].split(" ");
						upperMembership = new Triangular();
						((Triangular)upperMembership).setA(new Point(Double.parseDouble(points[0].split(";")[0]), Double.parseDouble(points[0].split(";")[1])));
						((Triangular)upperMembership).setB(new Point(Double.parseDouble(points[1].split(";")[0]), Double.parseDouble(points[1].split(";")[1])));
						((Triangular)upperMembership).setC(new Point(Double.parseDouble(points[2].split(";")[0]), Double.parseDouble(points[2].split(";")[1])));
					} else if (elements[6].equals("TRAPEZOIDAL")) {
						String[] points = elements[7].split(" ");
						upperMembership = new Trapezoidal();
						((Trapezoidal)upperMembership).setA(new Point(Double.parseDouble(points[0].split(";")[0]), Double.parseDouble(points[0].split(";")[1])));
						((Trapezoidal)upperMembership).setB(new Point(Double.parseDouble(points[1].split(";")[0]), Double.parseDouble(points[1].split(";")[1])));
						((Trapezoidal)upperMembership).setC(new Point(Double.parseDouble(points[2].split(";")[0]), Double.parseDouble(points[2].split(";")[1])));
						((Trapezoidal)upperMembership).setD(new Point(Double.parseDouble(points[3].split(";")[0]), Double.parseDouble(points[3].split(";")[1])));
					}
				} else if (elements[3].equals("TYPE1")) {
					if (elements[4].equals("TRIANGAL")) {
						String[] points = elements[5].split(" ");
						membership = new Triangular();
						((Triangular)membership).setA(new Point(Double.parseDouble(points[0].split(";")[0]), Double.parseDouble(points[0].split(";")[1])));
						((Triangular)membership).setB(new Point(Double.parseDouble(points[1].split(";")[0]), Double.parseDouble(points[1].split(";")[1])));
						((Triangular)membership).setC(new Point(Double.parseDouble(points[2].split(";")[0]), Double.parseDouble(points[2].split(";")[1])));
					} else if (elements[4].equals("TRAPEZOIDAL")) {
						String[] points = elements[5].split(" ");
						membership = new Trapezoidal();
						((Trapezoidal)membership).setA(new Point(Double.parseDouble(points[0].split(";")[0]), Double.parseDouble(points[0].split(";")[1])));
						((Trapezoidal)membership).setB(new Point(Double.parseDouble(points[1].split(";")[0]), Double.parseDouble(points[1].split(";")[1])));
						((Trapezoidal)membership).setC(new Point(Double.parseDouble(points[2].split(";")[0]), Double.parseDouble(points[2].split(";")[1])));
						((Trapezoidal)membership).setD(new Point(Double.parseDouble(points[3].split(";")[0]), Double.parseDouble(points[3].split(";")[1])));
					}
				}
				
				IFuzzySet set = null;
				if (elements[3].equals("INTERVAL")) {
					FuzzySetType1 lowerSet = new FuzzySetType1();
					lowerSet.setMembershipFunction(lowerMembership);
					FuzzySetType1 upperSet = new FuzzySetType1();
					upperSet.setMembershipFunction(upperMembership);
					
					set = new IntervalFuzzySet1();
					set.setLowerFuzzySet(lowerSet);
					set.setUpperFuzzySet(upperSet);
				} else if (elements[3].equals("TYPE1")) {
					set = new FuzzySetType1();
					set.setMembershipFunction(membership);
				}
				set.setUniverseOfDiscorse(universe);
				set.setColumn(elements[2]);
				sets.add(set);
				
				// Add to variable
				boolean isExists = false;
				for (Variable var : variables) {
					if (var.getName().equals(set.getColumn())) {
						isExists = true;
					}
				}
				
				if (!isExists) {
					Variable L = new Variable();
					L.setUniverse(set.getUniverseOfDiscorse());
					L.setName(set.getColumn());
					L.setColumn(set.getColumn());
					variables.add(L);
				}
				
				for (int i = 0; i < variables.size(); ++i) {
					if (variables.get(i).getName().equals(set.getColumn())) {
						boolean active = false;
						if (elements[10].equals("false")) {
							active = false;
						} else {
							active = true;
						}
						variables.get(i).addFuzzySet(elements[1], set, active);
					}
				}
			}
			
			
			if (line.equals("Quantifiers")) {
				nowQuantifiers = true;
			}
	}
	}

}
